home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume11 / quadtree / part01 next >
Encoding:
Text File  |  1990-04-03  |  23.4 KB  |  871 lines

  1. Newsgroups: comp.sources.misc
  2. subject: v11i092: Quadtree image encoder/viewer
  3. From: bobg+@andrew.cmu.edu (Robert Steven Glickstein)
  4. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5.  
  6. Posting-number: Volume 11, Issue 92
  7. Submitted-by: bobg+@andrew.cmu.edu (Robert Steven Glickstein)
  8. Archive-name: quadtree/part01
  9.  
  10. This package encodes bitmaps as "quadtrees."  A quadtree viewer for X11
  11. is included.  See the README file for more information.
  12.  
  13.  
  14.  
  15. ---- Enclosure ----
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then unpack
  18. # it by saving it into a file and typing "sh file".  To overwrite existing
  19. # files, type "sh file -c".  You can also feed this as standard input via
  20. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  21. # will see the following message at the end:
  22. #        "End of shell archive."
  23. # Contents:  README Makefile quadtree.c quadtree.h ras2qt.c xqtdisp.c
  24. # Wrapped by bobg@ephrata.andrew.cmu.edu on Fri Mar 30 11:27:15 1990
  25. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  26. if test -f README -a "${1}" != "-c" ; then 
  27.   echo shar: Will not over-write existing file \"README\"
  28. else
  29. echo shar: Extracting \"README\" \(3905 characters\)
  30. sed "s/^X//" >README <<'END_OF_README'
  31. XQUADTREE IMAGES by Bob Glickstein
  32. X
  33. XA ``quadtree'' is a means of encoding an image as a tree structure.
  34. XEach node of the tree has up to four children.  The root node
  35. Xrepresents the entire image; its children represent the four quadrants
  36. Xof the entire image; their children represent the sixteen
  37. Xsubquadrants; the children of those represent the sixty-four
  38. Xsub-subquadrants, and so on.
  39. X
  40. XA leaf node corresponds to a single pixel, and is marked with the
  41. Xcolor of that pixel (in this implementation, black or white only).  If
  42. Xa non-leaf node has two or more children of the same color, then that
  43. Xcolor is stored in the parent and the children are deleted.  Thus, if
  44. Xan entire quadrant (subquadrant, sub-subquadrant, etc.) of the image
  45. Xis white, that information can be stored in a single quadtree node,
  46. Xand all of the children of that node can be removed.
  47. X
  48. XFor certain images, this encoding yields enormous savings in storage
  49. Xsize.  Such images are typically line drawings or other bitmaps with
  50. Xseveral areas of solid black or white.  Images with a lot of dithering
  51. Xor stippling, such as scanned images, tend to yield little or no
  52. Xsavings in space.
  53. X
  54. XAn amusing aspect of quadtrees is that they can be displayed according
  55. Xto a depth-first or a breadth-first traversal of the tree.  In a
  56. Xdepth-first traversal, first the prodemonant color of the entire image
  57. Xis displayed; then the predominant color of the first quadrant is
  58. Xdisplayed; then the predominant color of the first subquadrant of the
  59. Xfirst quadrant, and so on.  The user can watch the quadrants and
  60. Xsubquadrants being drawn.  A breadth-first traversal, however, is much
  61. Xmore interesting.  Since it displays first the predominant color of
  62. Xthe entire image, followed by the predominant colors of the four major
  63. Xquadrants, followed by the predominant colors or the sixteen
  64. Xsubquadrants, and so on, the effect is one of a gradually resolving
  65. Ximage with finer and finer detail at each step.
  66. X
  67. X-----
  68. X
  69. XIncluded are two programs, ras2qt and xqtdisp.
  70. X
  71. XRas2qt is a filter which reads a raster on the standard input and
  72. Xproduces a quadtree on the standard output, as in:
  73. X
  74. X    ras2qt < input.cmuwm > output.qt
  75. X
  76. XThe input raster is in CMU WM format.  Jeff Poskanzer's latest
  77. XPortable Bitmap package (pbmplus, available on X11r4) includes filters
  78. Xfor converting images to cmuwm format.
  79. X
  80. X    (some sequence of filters) | pbmtocmuwm | ras2qt > output.qt
  81. X
  82. XExpect ras2qt to spend several silent and intent seconds calculating
  83. Xand writing the quadtree.
  84. X
  85. XXqtdisp is a quadtree viewer for X11.  It can be used as:
  86. X
  87. X    xqtdisp quadtree-file
  88. X
  89. Xin which case it will display the image depth-first; or as:
  90. X
  91. X    xqtdisp -b quadtree-file
  92. X
  93. Xin which case it will display the image breadth-first.  In both cases,
  94. Xthe program requires several seconds to parse the quadtree before
  95. Xcreating a window for displaying the image.  The user will be prompted
  96. Xto press ENTER to begin displaying, and, when the traversal is
  97. Xcompleted, will again be asked to press ENTER to exit the program.
  98. X
  99. XXqtdisp requires a lot of memory, especially in the breadth-first
  100. Xcase.  For breadth-first traversals of large (> 70k) quadtrees, it may
  101. Xbe necessary to do an ``unlimit'' first (csh users only), as in:
  102. X
  103. X    (unlimit; xqtdisp -b large-quadtree)
  104. X
  105. X-----
  106. X
  107. XThis software was written by Bob Glickstein (bobg@andrew.cmu.edu).  It
  108. Xis in the public domain and may be freely copied, modified and
  109. Xdistributed.  I provide no warranty for, and assume no responsibility
  110. Xfor this software.  I'd like to hear from anyone with ideas or
  111. Xcomments.
  112. X
  113. X-----
  114. X
  115. XComing soon:
  116. X
  117. X    - pbmtoqt
  118. X    - qttopbm
  119. X    - man pages
  120. X    - sample quadtrees
  121. X    - Faster execution
  122. X
  123. X-----
  124. X
  125. XNote that the routine QT_Bitmap_Read (in quadtree.c) makes an
  126. Xassumption about the byte order of your machine when reading the width
  127. Xand height of the raster.  You may need to modify this section if your
  128. Xmachine does not store 32-bit integers in most-significant-byte-first
  129. Xorder.
  130. END_OF_README
  131. if test 3905 -ne `wc -c <README`; then
  132.     echo shar: \"README\" unpacked with wrong size!
  133. fi
  134. # end of overwriting check
  135. fi
  136. if test -f Makefile -a "${1}" != "-c" ; then 
  137.   echo shar: Will not over-write existing file \"Makefile\"
  138. else
  139. echo shar: Extracting \"Makefile\" \(825 characters\)
  140. sed "s/^X//" >Makefile <<'END_OF_Makefile'
  141. XDESTDIR = /afs/andrew.cmu.edu/usr12/bobg
  142. XBINDIR = bin
  143. X
  144. XINSTALL = install
  145. X
  146. XINSTFLAGS = -c -o bobg -s
  147. X
  148. Xall: ras2qt xqtdisp
  149. X
  150. Xinstall: all
  151. X    $(INSTALL) $(INSTFLAGS) ras2qt $(DESTDIR)/$(BINDIR)
  152. X    $(INSTALL) $(INSTFLAGS) xqtdisp $(DESTDIR)/$(BINDIR)
  153. X
  154. Xras2qt: ras2qt.o quadtree.o
  155. X    cc -o ras2qt ras2qt.o quadtree.o
  156. X
  157. Xras2qt.o: ras2qt.c quadtree.h
  158. X    cc -O -I. -c ras2qt.c
  159. X
  160. Xquadtree.o: quadtree.c quadtree.h
  161. X    cc -O -I. -c quadtree.c
  162. X
  163. Xxqtdisp.o: xqtdisp.c quadtree.h
  164. X    cc -O -I. -c xqtdisp.o xqtdisp.c
  165. X
  166. Xxqtdisp: xqtdisp.o quadtree.o
  167. X    cc -o xqtdisp xqtdisp.o quadtree.o -lX11
  168. X
  169. Xclean:
  170. X    -rm -f xqtdisp ras2qt *.o *.BAK *.CKP *~ a.out mon.out gmon.out core quadtree.shar
  171. X
  172. Xquadtree.shar: README Makefile quadtree.c quadtree.h ras2qt.c xqtdisp.c
  173. X    -rm -f quadtree.shar
  174. X    shar README Makefile quadtree.c quadtree.h ras2qt.c xqtdisp.c > quadtree.shar
  175. END_OF_Makefile
  176. if test 825 -ne `wc -c <Makefile`; then
  177.     echo shar: \"Makefile\" unpacked with wrong size!
  178. fi
  179. # end of overwriting check
  180. fi
  181. if test -f quadtree.c -a "${1}" != "-c" ; then 
  182.   echo shar: Will not over-write existing file \"quadtree.c\"
  183. else
  184. echo shar: Extracting \"quadtree.c\" \(7638 characters\)
  185. sed "s/^X//" >quadtree.c <<'END_OF_quadtree.c'
  186. X#include <stdio.h>
  187. X#include <quadtree.h>
  188. X
  189. X#define ColorsAgree(c1,c2) ((c1)?(c2):(!(c2)))
  190. X
  191. Xstatic char     BitBuffer;
  192. Xstatic int      BitPos;
  193. X
  194. Xextern char    *malloc();
  195. X
  196. Xint             QT_Bitmap_Bit(b, x, y)
  197. XQT_Bitmap_t    *b;
  198. Xint             x, y;
  199. X{
  200. X    int             index, byte, offset;
  201. X
  202. X    index = (y + b->y) * b->fullwidth + (x + b->x);
  203. X    byte = index / 8;
  204. X    offset = index % 8;
  205. X    return (b->bits[byte] & (1 << offset));
  206. X}
  207. X
  208. Xvoid            QT_Bitmap_SetBit(b, x, y, val)
  209. XQT_Bitmap_t    *b;
  210. Xint             x, y, val;
  211. X{
  212. X    int             index, byte, offset;
  213. X
  214. X    index = (y + b->y) * b->fullwidth + (x + b->x);
  215. X    byte = index / 8;
  216. X    offset = index % 8;
  217. X    if (val)
  218. X    b->bits[byte] |= (1 << offset);
  219. X    else
  220. X    b->bits[byte] &= ~(1 << offset);
  221. X}
  222. X
  223. Xint             QT_Bitmap_Init(b, x, y, width, height, ref)
  224. XQT_Bitmap_t    *b;
  225. Xint             width, height;
  226. XQT_Bitmap_t    *ref;
  227. X{
  228. X    b->x = x;
  229. X    b->y = y;
  230. X    b->width = width;
  231. X    b->height = height;
  232. X    if (ref) {
  233. X    b->x += ref->x;
  234. X    b->y += ref->y;
  235. X    b->bits = ref->bits;
  236. X    b->fullwidth = ref->fullwidth;
  237. X    b->fullheight = ref->fullheight;
  238. X    return (0);
  239. X    }
  240. X    b->fullwidth = width;
  241. X    b->fullheight = height;
  242. X    if (b->bits = malloc(width * height / 8 + 1)) {
  243. X    bzero(b->bits, width * height / 8 + 1);
  244. X    return (0);
  245. X    }
  246. X    return (1);
  247. X}
  248. X
  249. XQT_TreeNode_t  *QT_TreeNode_New(color, ul, ur, ll, lr)
  250. Xint             color;
  251. XQT_TreeNode_t  *ul, *ur, *ll, *lr;
  252. X{
  253. X    QT_TreeNode_t  *result = (QT_TreeNode_t *) malloc(sizeof(QT_TreeNode_t));
  254. X
  255. X    if (result) {
  256. X    result->color = color;
  257. X    result->children[0] = ul;
  258. X    result->children[1] = ur;
  259. X    result->children[2] = ll;
  260. X    result->children[3] = lr;
  261. X    }
  262. X    return (result);
  263. X}
  264. X
  265. Xvoid            QT_TreeNode_Destroy(node)
  266. XQT_TreeNode_t  *node;
  267. X{
  268. X    int             i;
  269. X    QT_TreeNode_t  *child;
  270. X
  271. X    for (i = 0; i < 4; ++i) {
  272. X    if (child = QT_TreeNode_Child(node, i))
  273. X        QT_TreeNode_Destroy(child);
  274. X    }
  275. X    free(node);
  276. X}
  277. X
  278. Xstatic int      TreeAgrees(color, node)
  279. Xint             color;
  280. XQT_TreeNode_t  *node;
  281. X{
  282. X    return ((ColorsAgree(color, QT_TreeNode_Color(node)))
  283. X        && ((!(QT_TreeNode_Child(node, 0)))
  284. X        || TreeAgrees(color, QT_TreeNode_Child(node, 0)))
  285. X        && ((!(QT_TreeNode_Child(node, 1)))
  286. X        || TreeAgrees(color, QT_TreeNode_Child(node, 1)))
  287. X        && ((!(QT_TreeNode_Child(node, 2)))
  288. X        || TreeAgrees(color, QT_TreeNode_Child(node, 2)))
  289. X        && ((!(QT_TreeNode_Child(node, 3)))
  290. X        || TreeAgrees(color,
  291. X                  QT_TreeNode_Child(node, 3))));
  292. X}
  293. X
  294. XQT_TreeNode_t  *QT_BitmapToTree(b)
  295. XQT_Bitmap_t    *b;
  296. X{
  297. X    QT_Bitmap_t     ulbm, urbm, llbm, lrbm;
  298. X    QT_TreeNode_t  *ulqt, *urqt, *llqt, *lrqt;
  299. X    int             h = QT_Bitmap_Height(b), w = QT_Bitmap_Width(b), h2, w2;
  300. X    int             ones = 0, zeroes = 0, color;
  301. X
  302. X    switch (w * h) {
  303. X    case 0:
  304. X        return 0;
  305. X    case 1:
  306. X        return (QT_TreeNode_New(QT_Bitmap_Bit(b, 0, 0),
  307. X                    0, 0, 0, 0));
  308. X    }
  309. X    /* It's a non-trivial bitmap */
  310. X    h2 = h >> 1;
  311. X    w2 = w >> 1;
  312. X    (void) QT_Bitmap_Init(&ulbm, 0, 0, w2, h2, b);
  313. X    (void) QT_Bitmap_Init(&urbm, w2, 0, w - w2, h2, b);
  314. X    (void) QT_Bitmap_Init(&llbm, 0, h2, w2, h - h2, b);
  315. X    (void) QT_Bitmap_Init(&lrbm, w2, h2, w - w2, h - h2, b);
  316. X    ulqt = QT_BitmapToTree(&ulbm);
  317. X    urqt = QT_BitmapToTree(&urbm);
  318. X    llqt = QT_BitmapToTree(&llbm);
  319. X    lrqt = QT_BitmapToTree(&lrbm);
  320. X    if (ulqt) {
  321. X    if (QT_TreeNode_Color(ulqt))
  322. X        ++ones;
  323. X    else
  324. X        ++zeroes;
  325. X    }
  326. X    if (urqt) {
  327. X    if (QT_TreeNode_Color(urqt))
  328. X        ++ones;
  329. X    else
  330. X        ++zeroes;
  331. X    }
  332. X    if (llqt) {
  333. X    if (QT_TreeNode_Color(llqt))
  334. X        ++ones;
  335. X    else
  336. X        ++zeroes;
  337. X    }
  338. X    if (lrqt) {
  339. X    if (QT_TreeNode_Color(lrqt))
  340. X        ++ones;
  341. X    else
  342. X        ++zeroes;
  343. X    }
  344. X    color = (ones > zeroes) ? 1 : 0;
  345. X    if (ulqt) {
  346. X    if (TreeAgrees(color, ulqt)) {
  347. X        QT_TreeNode_Destroy(ulqt);
  348. X        ulqt = 0;
  349. X    }
  350. X    }
  351. X    if (urqt) {
  352. X    if (TreeAgrees(color, urqt)) {
  353. X        QT_TreeNode_Destroy(urqt);
  354. X        urqt = 0;
  355. X    }
  356. X    }
  357. X    if (llqt) {
  358. X    if (TreeAgrees(color, llqt)) {
  359. X        QT_TreeNode_Destroy(llqt);
  360. X        llqt = 0;
  361. X    }
  362. X    }
  363. X    if (lrqt) {
  364. X    if (TreeAgrees(color, lrqt)) {
  365. X        QT_TreeNode_Destroy(lrqt);
  366. X        lrqt = 0;
  367. X    }
  368. X    }
  369. X    return (QT_TreeNode_New(color, ulqt, urqt, llqt, lrqt));
  370. X}
  371. X
  372. Xstatic void     BitWrite(bit, fp)
  373. Xint             bit;
  374. XFILE           *fp;
  375. X{
  376. X    if (bit)
  377. X    BitBuffer |= (1 << BitPos);
  378. X    else
  379. X    BitBuffer &= ~(1 << BitPos);
  380. X    if ((--BitPos) < 0) {
  381. X    BitPos = 7;
  382. X    fputc(BitBuffer, fp);
  383. X    }
  384. X}
  385. X
  386. X#define BitFlush(fp) (fputc(BitBuffer,(fp)))
  387. X
  388. Xstatic void     QT_TreeNode_Write(fp, node, fmt)
  389. XFILE           *fp;
  390. XQT_TreeNode_t  *node;
  391. Xchar            fmt;
  392. X{
  393. X    int             i;
  394. X    QT_TreeNode_t  *child;
  395. X
  396. X    switch (fmt) {
  397. X    case 0:
  398. X        BitWrite(0, fp);
  399. X        BitWrite(QT_TreeNode_Color(node), fp);
  400. X        for (i = 0; i < 4; ++i) {
  401. X        if (child = QT_TreeNode_Child(node, i))
  402. X            QT_TreeNode_Write(fp, child, fmt);
  403. X        else
  404. X            BitWrite(1, fp);
  405. X        }
  406. X        break;
  407. X    case 1:
  408. X        BitWrite(0, fp);
  409. X        BitWrite(QT_TreeNode_Color(node), fp);
  410. X        if (QT_TreeNode_Child(node, 0)
  411. X        || QT_TreeNode_Child(node, 1)
  412. X        || QT_TreeNode_Child(node, 2)
  413. X        || QT_TreeNode_Child(node, 3)) {
  414. X        for (i = 0; i < 4; ++i) {
  415. X            if (child = QT_TreeNode_Child(node, i))
  416. X            QT_TreeNode_Write(fp, child, fmt);
  417. X            else {
  418. X            BitWrite(1, fp);
  419. X            BitWrite(0, fp);
  420. X            }
  421. X        }
  422. X        }
  423. X        else {
  424. X        BitWrite(1, fp);
  425. X        BitWrite(1, fp);
  426. X        }
  427. X        break;
  428. X    }
  429. X}
  430. X
  431. Xvoid            QT_Tree_Write(fp, node, fmt, w, h)
  432. XFILE           *fp;
  433. XQT_TreeNode_t  *node;
  434. Xchar            fmt;
  435. Xshort           w, h;
  436. X{
  437. X    BitPos = 7;
  438. X    fputc(fmt, fp);
  439. X    fputc(w % 256, fp);
  440. X    fputc(w / 256, fp);
  441. X    fputc(h % 256, fp);
  442. X    fputc(h / 256, fp);
  443. X    QT_TreeNode_Write(fp, node, fmt);
  444. X    BitFlush(fp);
  445. X}
  446. X
  447. Xstatic int      BitRead(fp)
  448. XFILE           *fp;
  449. X{
  450. X    if ((--BitPos) < 0) {
  451. X    BitPos = 7;
  452. X    BitBuffer = fgetc(fp);
  453. X    }
  454. X    return (BitBuffer & (1 << BitPos));
  455. X}
  456. X
  457. Xstatic QT_TreeNode_t *QT_TreeNode_Read(fp, fmt, extra)
  458. XFILE           *fp;
  459. Xchar            fmt;
  460. Xint            *extra;
  461. X{
  462. X    int             bit = BitRead(fp), bit2, nochildren, dummy;
  463. X    QT_TreeNode_t  *ul, *ur, *ll, *lr;
  464. X
  465. X    switch (fmt) {
  466. X    case 0:
  467. X        if (bit) {
  468. X        return (0);
  469. X        }
  470. X        bit = BitRead(fp);
  471. X        ul = QT_TreeNode_Read(fp, fmt, &dummy);
  472. X        ur = QT_TreeNode_Read(fp, fmt, &dummy);
  473. X        ll = QT_TreeNode_Read(fp, fmt, &dummy);
  474. X        lr = QT_TreeNode_Read(fp, fmt, &dummy);
  475. X        return (QT_TreeNode_New(bit, ul, ur, ll, lr));
  476. X    case 1:
  477. X        bit2 = BitRead(fp);
  478. X        if (bit) {
  479. X        *extra = bit2;
  480. X        return (0);
  481. X        }
  482. X        ul = QT_TreeNode_Read(fp, fmt, &nochildren);
  483. X        if ((!ul) && nochildren)
  484. X        return (QT_TreeNode_New(bit2, 0, 0, 0, 0));
  485. X        ur = QT_TreeNode_Read(fp, fmt, &dummy);
  486. X        ll = QT_TreeNode_Read(fp, fmt, &dummy);
  487. X        lr = QT_TreeNode_Read(fp, fmt, &dummy);
  488. X        return (QT_TreeNode_New(bit2, ul, ur, ll, lr));
  489. X    }
  490. X}
  491. X
  492. XQT_TreeNode_t  *QT_Tree_Read(fp, w, h)
  493. XFILE           *fp;
  494. Xshort          *w, *h;
  495. X{
  496. X    char            fmt = fgetc(fp);
  497. X    int             dummy;
  498. X
  499. X    BitPos = 0;
  500. X    *w = fgetc(fp);
  501. X    *w += fgetc(fp) * 256;
  502. X    *h = fgetc(fp);
  503. X    *h += fgetc(fp) * 256;
  504. X    return (QT_TreeNode_Read(fp, fmt, &dummy));
  505. X}
  506. X
  507. Xint             QT_Bitmap_Read(b, fp)  /* B is an *uninitialized* bitmap */
  508. XQT_Bitmap_t    *b;
  509. XFILE           *fp;
  510. X{
  511. X    int             x, y, c;
  512. X    char            buf[4];
  513. X    long            w, h;
  514. X
  515. X    fread(buf, 4, 1, fp);
  516. X    fread(&w, 4, 1, fp);
  517. X    fread(&h, 4, 1, fp);
  518. X    fread(buf, 2, 1, fp);
  519. X    if (QT_Bitmap_Init(b, 0, 0, (int) w, (int) h, 0))
  520. X    return (1);
  521. X    BitPos = -1;
  522. X    for (y = 0; y < h; ++y) {
  523. X    for (x = 0; x < w; ++x) {
  524. X        c = BitRead(fp);
  525. X        QT_Bitmap_SetBit(b, x, y, !c);
  526. X    }
  527. X    BitPos = -1;
  528. X    }
  529. X    return (0);
  530. X}
  531. END_OF_quadtree.c
  532. if test 7638 -ne `wc -c <quadtree.c`; then
  533.     echo shar: \"quadtree.c\" unpacked with wrong size!
  534. fi
  535. # end of overwriting check
  536. fi
  537. if test -f quadtree.h -a "${1}" != "-c" ; then 
  538.   echo shar: Will not over-write existing file \"quadtree.h\"
  539. else
  540. echo shar: Extracting \"quadtree.h\" \(1318 characters\)
  541. sed "s/^X//" >quadtree.h <<'END_OF_quadtree.h'
  542. Xtypedef struct {
  543. X    short           x, y, width, height, fullwidth, fullheight;
  544. X    char           *bits;
  545. X}               QT_Bitmap_t;
  546. X
  547. Xtypedef struct _QT_TreeNode {
  548. X    short           color;
  549. X    struct _QT_TreeNode *children[4];
  550. X}               QT_TreeNode_t;
  551. X
  552. X#define QT_Bitmap_Width(b) ((b)->width)
  553. X#define QT_Bitmap_Height(b) ((b)->height)
  554. X
  555. X#define QT_TreeNode_Color(t) ((t)->color)
  556. X#define QT_TreeNode_Child(t,n) ((t)->children[n])
  557. X#define QT_TreeNode_UpperLeft(t) (QT_TreeNode_Child((t),0))
  558. X#define QT_TreeNode_UpperRight(t) (QT_TreeNode_Child((t),1))
  559. X#define QT_TreeNode_LowerLeft(t) (QT_TreeNode_Child((t),2))
  560. X#define QT_TreeNode_LowerRight(t) (QT_TreeNode_Child((t),3))
  561. X#define QT_TreeNode_SetColor(t,c) (((t)->color)=(c))
  562. X#define QT_TreeNode_SetUpperLeft(t,v) (((t)->children[0])=(v))
  563. X#define QT_TreeNode_SetUpperRight(t,v) (((t)->children[1])=(v))
  564. X#define QT_TreeNode_SetLowerLeft(t,v) (((t)->children[2])=(v))
  565. X#define QT_TreeNode_SetLowerRight(t,v) (((t)->children[3])=(v))
  566. X
  567. Xextern QT_TreeNode_t *QT_BitmapToTree();
  568. Xextern int      QT_Bitmap_Bit();
  569. Xextern int      QT_Bitmap_Init();
  570. Xextern int      QT_Bitmap_Read();
  571. Xextern void     QT_Bitmap_SetBit();
  572. Xextern void     QT_TreeNode_Destroy();
  573. Xextern QT_TreeNode_t *QT_TreeNode_New();
  574. Xextern QT_TreeNode_t *QT_Tree_Read();
  575. Xextern void     QT_Tree_Write();
  576. END_OF_quadtree.h
  577. if test 1318 -ne `wc -c <quadtree.h`; then
  578.     echo shar: \"quadtree.h\" unpacked with wrong size!
  579. fi
  580. # end of overwriting check
  581. fi
  582. if test -f ras2qt.c -a "${1}" != "-c" ; then 
  583.   echo shar: Will not over-write existing file \"ras2qt.c\"
  584. else
  585. echo shar: Extracting \"ras2qt.c\" \(535 characters\)
  586. sed "s/^X//" >ras2qt.c <<'END_OF_ras2qt.c'
  587. X#include <stdio.h>
  588. X#include <quadtree.h>
  589. X
  590. Xextern int      optind;
  591. Xextern char    *optarg;
  592. X
  593. Xmain(argc, argv)
  594. X{
  595. X    QT_Bitmap_t     Bitmap;
  596. X    QT_TreeNode_t  *root;
  597. X    int             c;
  598. X    char            fmt = 0;
  599. X
  600. X    while ((c = getopt(argc, argv, "12")) != EOF) {
  601. X    switch (c) {
  602. X        case '1':
  603. X        case '2':
  604. X        fmt = c - '1';
  605. X        break;
  606. X    }
  607. X    }
  608. X    QT_Bitmap_Read(&Bitmap, stdin);
  609. X    root = QT_BitmapToTree(&Bitmap);
  610. X    QT_Tree_Write(stdout, root, fmt,
  611. X          QT_Bitmap_Width(&Bitmap),
  612. X          QT_Bitmap_Height(&Bitmap));
  613. X    exit(0);
  614. X}
  615. END_OF_ras2qt.c
  616. if test 535 -ne `wc -c <ras2qt.c`; then
  617.     echo shar: \"ras2qt.c\" unpacked with wrong size!
  618. fi
  619. # end of overwriting check
  620. fi
  621. if test -f xqtdisp.c -a "${1}" != "-c" ; then 
  622.   echo shar: Will not over-write existing file \"xqtdisp.c\"
  623. else
  624. echo shar: Extracting \"xqtdisp.c\" \(5375 characters\)
  625. sed "s/^X//" >xqtdisp.c <<'END_OF_xqtdisp.c'
  626. X#include <stdio.h>
  627. X#include <quadtree.h>
  628. X#include <X11/Xlib.h>
  629. X#include <X11/Xatom.h>
  630. X#include <X11/Xutil.h>
  631. X
  632. Xextern char    *getenv(), *optarg, *malloc();
  633. Xextern int      optind;
  634. Xextern FILE    *fopen();
  635. X
  636. XDisplay        *QTDisplay;
  637. XWindow          QTWindow;
  638. XGC              WhiteRegion, BlackRegion;
  639. Xint             Verbose;
  640. X
  641. Xstruct Qentry {
  642. X    QT_TreeNode_t  *node;
  643. X    struct Qentry  *next, *prev;
  644. X    short           x, y, width, height, parent;
  645. X}              *Head, *Tail, *Freelist;
  646. X
  647. X#define ColorsAgree(c1,c2) ((c1)?(c2):(!(c2)))
  648. X
  649. Xstruct Qentry  *NewQentry()
  650. X{
  651. X    struct Qentry  *result, *ptr;
  652. X    int             i;
  653. X
  654. X    if (result = Freelist) {
  655. X    Freelist = result->next;
  656. X    return (result);
  657. X    }
  658. X    result = (struct Qentry *) malloc(64 *
  659. X                      (sizeof(struct Qentry)));
  660. X    for (i = 0, ptr = result; i < 63; ++ptr, ++i) {
  661. X    ptr->next = ptr + 1;
  662. X    }
  663. X    ptr->next = Freelist;
  664. X    Freelist = result->next;
  665. X    return (result);
  666. X}
  667. X
  668. Xvoid            ReleaseQentry(qe)
  669. Xstruct Qentry  *qe;
  670. X{
  671. X    qe->next = Freelist;
  672. X    Freelist = qe;
  673. X}
  674. X
  675. Xmain(argc, argv)
  676. Xint             argc;
  677. Xchar          **argv;
  678. X{
  679. X    int             c, breadth = 0, screen;
  680. X    short           width, height;
  681. X    QT_TreeNode_t  *Tree;
  682. X    FILE           *fp;
  683. X    char           *displayname;
  684. X    Window          rwindow;
  685. X    XGCValues       gcv;
  686. X
  687. X    Freelist = 0;
  688. X    Verbose = 0;
  689. X    while ((c = getopt(argc, argv, "bdv")) != EOF) {
  690. X    switch (c) {
  691. X        case 'b':
  692. X        breadth = 1;
  693. X        break;
  694. X        case 'd':
  695. X        breadth = 0;
  696. X        break;
  697. X        case 'v':
  698. X        ++Verbose;
  699. X        break;
  700. X    }
  701. X    }
  702. X    if (!(fp = fopen(argv[optind], "r"))) {
  703. X    exit(1);
  704. X    }
  705. X    Tree = QT_Tree_Read(fp, &width, &height);
  706. X    if (!(displayname = getenv("DISPLAY")))
  707. X    displayname = ":0";
  708. X    QTDisplay = XOpenDisplay(displayname);
  709. X    screen = DefaultScreen(QTDisplay);
  710. X    rwindow = RootWindow(QTDisplay, screen);
  711. X    QTWindow = XCreateSimpleWindow(QTDisplay, rwindow,
  712. X                   0, 0, width, height,
  713. X                   1, WhitePixel(QTDisplay, screen),
  714. X                   BlackPixel(QTDisplay, screen));
  715. X    XMapWindow(QTDisplay, QTWindow);
  716. X    XSync(QTDisplay, 0);
  717. X    gcv.foreground = WhitePixel(QTDisplay, screen);
  718. X    gcv.function = GXset;
  719. X    WhiteRegion = XCreateGC(QTDisplay, QTWindow,
  720. X                GCFunction | GCForeground, &gcv);
  721. X    gcv.function = GXclear;
  722. X    BlackRegion = XCreateGC(QTDisplay, QTWindow,
  723. X                GCFunction | GCForeground, &gcv);
  724. X    puts("Press ENTER to begin");
  725. X    while ('\n' != getchar());
  726. X    if (breadth)
  727. X    BreadthDraw(Tree, width, height);
  728. X    else
  729. X    DepthDraw(Tree, width, height);
  730. X    XSync(QTDisplay, 0);
  731. X    puts("Press ENTER to terminate");
  732. X    while ('\n' != getchar());
  733. X    exit(0);
  734. X}
  735. X
  736. Xdepthdraw(node, x, y, w, h, parent)
  737. XQT_TreeNode_t  *node;
  738. Xint             x, y, w, h, parent;
  739. X{
  740. X    int             color = QT_TreeNode_Color(node), w2, h2;
  741. X    QT_TreeNode_t  *child;
  742. X
  743. X    if (!(ColorsAgree(color, parent))) {
  744. X    if (Verbose) {
  745. X        fprintf(stderr, "Filling (%d,%d) (%dx%d) [%s]\n",
  746. X            x, y, w, h,
  747. X            color ? "black" : "white");
  748. X    }
  749. X    XFillRectangle(QTDisplay, QTWindow,
  750. X               color ? BlackRegion : WhiteRegion,
  751. X               x, y, w, h);
  752. X    }
  753. X    w2 = w >> 1;
  754. X    h2 = h >> 1;
  755. X    if (child = QT_TreeNode_UpperLeft(node)) {
  756. X    depthdraw(child, x, y, w2, h2, color);
  757. X    }
  758. X    if (child = QT_TreeNode_UpperRight(node)) {
  759. X    depthdraw(child, x + w2, y, w - w2, h2, color);
  760. X    }
  761. X    if (child = QT_TreeNode_LowerLeft(node)) {
  762. X    depthdraw(child, x, y + h2, w2, h - h2, color);
  763. X    }
  764. X    if (child = QT_TreeNode_LowerRight(node)) {
  765. X    depthdraw(child, x + w2, y + h2, w - w2, h - h2, color);
  766. X    }
  767. X}
  768. X
  769. XDepthDraw(node, width, height)
  770. XQT_TreeNode_t  *node;
  771. Xint             width, height;
  772. X{
  773. X    depthdraw(node, 0, 0, width, height, 1);
  774. X}
  775. X
  776. XQueueInit()
  777. X{
  778. X    Head = Tail = 0;
  779. X}
  780. X
  781. XQueueAdd(node, x, y, w, h, parent)
  782. XQT_TreeNode_t  *node;
  783. Xint             x, y, w, h, parent;
  784. X{
  785. X    struct Qentry  *result = NewQentry();
  786. X
  787. X    result->node = node;
  788. X    result->x = x;
  789. X    result->y = y;
  790. X    result->width = w;
  791. X    result->height = h;
  792. X    result->parent = parent;
  793. X    result->next = 0;
  794. X    result->prev = Tail;
  795. X    if (Tail)
  796. X    Tail->next = result;
  797. X    Tail = result;
  798. X    if (!Head)
  799. X    Head = result;
  800. X}
  801. X
  802. XQueueDo()
  803. X{
  804. X    struct Qentry  *entry;
  805. X    QT_TreeNode_t  *node, *child;
  806. X    int             x, y, w, h, color, parent, w2, h2;
  807. X
  808. X    for (entry = Head; entry; entry = entry->next) {
  809. X    if (entry->prev)
  810. X        ReleaseQentry(entry->prev);
  811. X    node = entry->node;
  812. X    x = entry->x;
  813. X    y = entry->y;
  814. X    w = entry->width;
  815. X    h = entry->height;
  816. X    color = QT_TreeNode_Color(node);
  817. X    parent = entry->parent;
  818. X    if (!(ColorsAgree(color, parent))) {
  819. X        if (Verbose) {
  820. X        fprintf(stderr, "Filling (%d,%d) (%dx%d) [%s]\n",
  821. X            x, y, w, h,
  822. X            color ? "black" : "white");
  823. X        }
  824. X        XFillRectangle(QTDisplay, QTWindow,
  825. X               color ? BlackRegion : WhiteRegion,
  826. X               x, y, w, h);
  827. X    }
  828. X    w2 = w >> 1;
  829. X    h2 = h >> 1;
  830. X    if (child = QT_TreeNode_UpperLeft(node)) {
  831. X        QueueAdd(child, x, y, w2, h2, color);
  832. X    }
  833. X    if (child = QT_TreeNode_UpperRight(node)) {
  834. X        QueueAdd(child, x + w2, y, w - w2, h2, color);
  835. X    }
  836. X    if (child = QT_TreeNode_LowerLeft(node)) {
  837. X        QueueAdd(child, x, y + h2, w2, h - h2, color);
  838. X    }
  839. X    if (child = QT_TreeNode_LowerRight(node)) {
  840. X        QueueAdd(child, x + w2, y + h2, w - w2, h - h2, color);
  841. X    }
  842. X    }
  843. X}
  844. X
  845. XBreadthDraw(node, width, height)
  846. XQT_TreeNode_t  *node;
  847. Xint             width, height;
  848. X{
  849. X    QueueInit();
  850. X    QueueAdd(node, 0, 0, width, height, 1);
  851. X    QueueDo();
  852. X}
  853. END_OF_xqtdisp.c
  854. if test 5375 -ne `wc -c <xqtdisp.c`; then
  855.     echo shar: \"xqtdisp.c\" unpacked with wrong size!
  856. fi
  857. # end of overwriting check
  858. fi
  859. echo shar: End of shell archive.
  860. exit 0
  861.  
  862. ---- Enclosure ----
  863.  
  864. ______________                  _____________________________
  865. Bob Glickstein                | Internet: bobg@andrew.cmu.edu
  866. Information Technology Center | Bitnet:   bobg%andrew@cmuccvma.bitnet
  867. Carnegie Mellon University    | UUCP:     ...!harvard!andrew.cmu.edu!bobg
  868. Pittsburgh, PA  15213-3890    |
  869. (412) 268-6743                | Sinners can repent, but stupid is forever
  870.  
  871.